;;; Complete symbols at point using Pymacs.

;; Copyright (C) 2007  Skip Montanaro

;; Author:     Skip Montanaro
;; Maintainer: skip@pobox.com
;; Created:    Oct 2004
;; Keywords:   python pymacs emacs

;; This software is provided as-is, without express or implied warranty.
;; Permission to use, copy, modify, distribute or sell this software,
;; without fee, for any purpose and by any individual or organization, is
;; hereby granted, provided that the above copyright notice and this
;; paragraph appear in all copies.

;; Along with pycomplete.py this file allows programmers to complete Python
;; symbols within the current buffer.  See pycomplete.py for the Python side
;; of things and a short description of what to expect.

(require 'pymacs)
(require 'python-mode)

(pymacs-load "pycomplete")

(defun my-ac-pycomplete-prefix ()
  (save-excursion
    (if (re-search-backward "[^_a-zA-Z0-9.]\\([_a-zA-Z][_a-zA-Z0-9.]*\\)\\=" nil t)
        (match-beginning 1)
      (point))))

(defun py-find-global-imports ()
  (save-excursion
    (let (first-class-or-def imports)
      (goto-char (point-min))
      (setq first-class-or-def
            (re-search-forward "^ *\\(def\\|class\\) " nil t))
      (goto-char (point-min))
      (setq imports nil)
      (while (re-search-forward
              "^\\(import \\|from \\([A-Za-z_][A-Za-z_0-9]*\\) import \\).*"
              nil t)
        (setq imports (append imports
                              (list (buffer-substring-no-properties
                                     (match-beginning 0)
                                     (match-end 0))))))
      imports)))

(defvar my-ac-pycomplete-imports nil
  "")

(defvar my-ac-pycomplete-candidate-special-p nil
  "是否列出特殊变量")

(defvar my-ac-pycomplete-candidate-keywords-p t
  "是否列出关键字")

(defvar my-ac-pycomplete-keywords
  '("and"
    "assert"
    "break"
    "class"
    "continue"
    "def"
    "del"
    "elif"
    "else"
    "except"
    "exec"
    "finally"
    "for"
    "from"
    "global"
    "if"
    "import"
    "in"
    "is"
    "lambda"
    "not"
    "or"
    "pass"
    "print"
    "raise"
    "return"
    "try"
    "while")
  "python 的关键字")

(defun my-ac-pycomplete-candidate ()
  (let ((completions (pycomplete-pycomplete
                      ac-prefix my-ac-pycomplete-imports)))
    (unless my-ac-pycomplete-candidate-special-p
      (setq completions
            (delq nil
                  (mapcar (lambda (elt)
                            (unless (string-match "^__.*" elt) elt))
                          completions))))
    (setq completions (mapcar (lambda (c)
                                (concat ac-prefix c))
                              completions))
    (when my-ac-pycomplete-candidate-keywords-p
      (let ((reg (concat "^" (regexp-quote ac-prefix))))
        (dolist (kw my-ac-pycomplete-keywords)
          (when (string-match reg kw)
            (add-to-list 'completions kw t)))))
    completions))

(defface my-ac-pycomplete-candidate-face
  '((t (:background "sandybrown" :foreground "black")))
  "Face for pycomplete candidate.")

(defface my-ac-pycomplete-selection-face
  '((t (:background "coral3" :foreground "white")))
  "Face for the pycomplete selected candidate.")

(defvar my-ac-source-pycomplete
  '((init       . (setq my-ac-pycomplete-imports
                        (py-find-global-imports)))
    (candidates . my-ac-pycomplete-candidate)
    (prefix     . my-ac-pycomplete-prefix)
    (candidate-face . my-ac-pycomplete-candidate-face)
    (selection-face . my-ac-pycomplete-selection-face)
    (limit      . 0)))

(provide 'pycomplete)
